package controllers

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"

	"github.com/golang/glog"
	v1 "k8s.io/api/apps/v1"

	"eccgateway/pkg/config"
)

var k8sURL string

func GetDeploymentNamesByCameraModelName(w http.ResponseWriter, req *http.Request) {
	if len(k8sURL) == 0 {
		k8sURL = config.GetConfig().String("kubernetesAddress")
		glog.Infof("url is %v", k8sURL)
	}

	cameraName := req.URL.Query().Get("name")
	namespace := req.URL.Query().Get("namespace")
	if len(namespace) == 0 {
		namespace = "default"
	}

	models, err := GetModelDeployment(cameraName, namespace)
	if err != nil {
		msg := fmt.Sprintf("failed to get model deployment, %v", err)
		glog.Errorf(msg)
		w.WriteHeader(http.StatusInternalServerError)
		_, _ = w.Write([]byte(msg))
		return
	}

	cameraModel := make(map[string][]string)
	cameraModel[cameraName] = models

	bytes, err := json.Marshal(cameraModel)
	if err != nil {
		msg := fmt.Sprintf("camera model marshal error, %v", err)
		glog.Errorf(msg)
		w.WriteHeader(http.StatusInternalServerError)
		_, _ = w.Write([]byte(msg))
		return
	}
	_, _ = w.Write(bytes)
}

func DeleteDeploymentAndServiceByCameraModelName(w http.ResponseWriter, req *http.Request) {
	if len(k8sURL) == 0 {
		k8sURL = config.GetConfig().String("kubernetesAddress")
		glog.Infof("url is %v", k8sURL)
	}
	defer func() { _ = req.Body.Close() }()
	resource, err := ioutil.ReadAll(req.Body)
	if err != nil {
		msg := fmt.Sprintf("read request body error, %v", err)
		glog.Errorf(msg)
		w.WriteHeader(http.StatusBadRequest)
		_, _ = w.Write([]byte(msg))
		return
	}
	r := make(map[string]string)
	err = json.Unmarshal(resource, &r)
	if err != nil {
		msg := fmt.Sprintf("Unmarshal error when delete k8s resource, %v", err)
		glog.Errorf(msg)
		_, _ = w.Write([]byte(msg))
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	if len(r) != 0 {
		for _, v := range r {
			DeleteResources(v, "deployments")
			DeleteResources(v, "services")
		}
	}
}

func GetModelDeployment(cameraName, namespace string) ([]string, error) {

	resp, err := http.Get(k8sURL + "apis/apps/v1/namespaces/" + namespace + "/deployments")
	if err != nil {
		glog.Errorf("get kubernetes deployments error, %v", err)
		return []string{}, err
	}
	defer resp.Body.Close()
	deploymentListBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		glog.Errorf("read kubernetes deployments info error, %v", err)
		return []string{}, err
	}

	var deploymentList v1.DeploymentList
	err = json.Unmarshal(deploymentListBody, &deploymentList)
	if err != nil {
		glog.Errorf("Unmarshal kubernetes deployment list error, %v", err)
		return []string{}, err
	}

	var models = make([]string, 0)
	for _, item := range deploymentList.Items {
		if strings.Contains(item.Name, cameraName) {
			models = append(models, item.Name)
		}
	}
	return models, nil
}

func DeleteResources(resource, resType string) error {
	var resourceUrl string
	if resType == "deployments" {
		resourceUrl = k8sURL + "apis/apps/v1/namespaces/default/" + resType + "/" + resource
	} else {
		resourceUrl = k8sURL + "api/v1/namespaces/default/" + resType + "/" + resource
	}

	request, err := http.NewRequest(http.MethodDelete, resourceUrl, nil)
	if err != nil {
		glog.Errorf("http new request error: $v", err)
		return err
	}
	request.Header.Add("Accept", "application/json")
	request.Header.Add("Content-Type", "application/json")
	_, err = http.DefaultClient.Do(request)
	if err != nil {
		glog.Errorf("Delete resource error:", err)
		return err
	}
	return nil
}
